package Java_Concurrency_in_Practice.xinhaoliang;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Semaphore;

/**
 * 计数信号量用来控制同时访问某个特定资源的操作数量, 或者同时执行某个操作的数量. 
 * 计数信号量还可以用来实现某种资源池, 或者对容器施加边界
 * @author xiangke
 *
 * @param <T>
 */
public class BoundedHashset<T> {

	private final Set<T> set;
	
	private final Semaphore sem;
	
	public BoundedHashset(int bound) {
		this.set = Collections.synchronizedSet(new HashSet<T>());
		sem = new Semaphore(bound);
	}
	
	public boolean add(T o) throws InterruptedException {
		sem.acquire();
		boolean wasAdded = false;
		try {
			wasAdded = set.add(o);
			return wasAdded;
		} finally {
			if (!wasAdded) {
				sem.release();
			}
		}
	}
	
	public boolean remove (Object o) {
		boolean wasRemoved = set.remove(o);
		if (wasRemoved) {
			sem.release();
		}
		return wasRemoved;
	}
}
